import javax.swing.*;
import javax.swing.border.*;
import java.awt.event.*;
import java.util.Random;

public class CandadoGUI extends JFrame {

    /**
     * Creates new form CandadoGUI
     */
    public CandadoGUI() {
        initComponents();
        setResizable(false);
        
        //Pregunta cual candado quiere usar
        int respuesta = JOptionPane.showConfirmDialog(
                null,
                "¿Desea usar la clase Candado1? Si quiere usar la clase Candado2, seleccione \"No\"",
                "SELECCIONAR CLASE A UTILIZAR",
                JOptionPane.YES_NO_OPTION,
                JOptionPane.QUESTION_MESSAGE);
        
        //Dependiendo de la respuesta que selecciono el usuario, inicializa candado como Candado1 o Candado2
        if(respuesta == JOptionPane.YES_OPTION){
            JOptionPane.showMessageDialog(
                        null,
                        "Ha seleccionado Candado1",
                        "AVISO",
                        JOptionPane.INFORMATION_MESSAGE);
            candado = (iCandado)(new Candado1());
        }
        else if(respuesta == JOptionPane.NO_OPTION){
            JOptionPane.showMessageDialog(
                        null,
                        "Ha seleccionado Candado2",
                        "AVISO",
                        JOptionPane.INFORMATION_MESSAGE);
            candado = (iCandado)(new Candado2());
        }
    }

    private void initComponents() {

        pnlPantalla = new JPanel();
        spnNumero = new JSpinner();
        lblIngresados = new JLabel();
        pnlBotones = new JPanel();
        btnReset = new JButton();
        btnSet = new JButton();
        btnLock = new JButton();
        btnCambiar = new JButton();

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        pnlPantalla.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));

        spnNumero.setModel(new SpinnerNumberModel(0, 0, 25, 1));

        lblIngresados.setText("-");

        GroupLayout pnlPantallaLayout = new GroupLayout(pnlPantalla);
        pnlPantalla.setLayout(pnlPantallaLayout);
        pnlPantallaLayout.setHorizontalGroup(
            pnlPantallaLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(pnlPantallaLayout.createSequentialGroup()
                .addGap(108, 108, 108)
                .addComponent(spnNumero, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addContainerGap(100, Short.MAX_VALUE))
            .addComponent(lblIngresados, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        pnlPantallaLayout.setVerticalGroup(
            pnlPantallaLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(GroupLayout.Alignment.TRAILING, pnlPantallaLayout.createSequentialGroup()
                .addComponent(lblIngresados)
                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(spnNumero, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        pnlBotones.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));

        btnReset.setText("Reset");
        btnSet.setText("Set");
        btnLock.setText("Lock");
        btnCambiar.setText("New Key");

		btnReset.addActionListener(new ButtonListener());
		btnSet.addActionListener(new ButtonListener());
		btnLock.addActionListener(new ButtonListener());
		btnCambiar.addActionListener(new ButtonListener());

        GroupLayout pnlBotonesLayout = new GroupLayout(pnlBotones);
        pnlBotones.setLayout(pnlBotonesLayout);
        pnlBotonesLayout.setHorizontalGroup(
            pnlBotonesLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(pnlBotonesLayout.createSequentialGroup()
                .addGroup(pnlBotonesLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addGroup(pnlBotonesLayout.createSequentialGroup()
                        .addGap(33, 33, 33)
                        .addComponent(btnReset)
                        .addGap(29, 29, 29)
                        .addComponent(btnSet))
                    .addGroup(pnlBotonesLayout.createSequentialGroup()
                        .addGap(86, 86, 86)
                        .addGroup(pnlBotonesLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                            .addComponent(btnCambiar)
                            .addComponent(btnLock))))
                .addContainerGap(35, Short.MAX_VALUE))
        );

        pnlBotonesLayout.linkSize(SwingConstants.HORIZONTAL, new java.awt.Component[] {btnCambiar, btnLock, btnReset, btnSet});

        pnlBotonesLayout.setVerticalGroup(
            pnlBotonesLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(pnlBotonesLayout.createSequentialGroup()
                .addGroup(pnlBotonesLayout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                    .addComponent(btnReset)
                    .addComponent(btnSet))
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 12, Short.MAX_VALUE)
                .addComponent(btnLock)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(btnCambiar)
                .addContainerGap())
        );

        GroupLayout layout = new GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                    .addComponent(pnlPantalla, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                    .addComponent(pnlBotones, GroupLayout.Alignment.LEADING, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(pnlPantalla, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(pnlBotones, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

		btnLock.setEnabled(false);
		btnCambiar.setEnabled(false);

        pack();
    }// </editor-fold>                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(CandadoGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(CandadoGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(CandadoGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(CandadoGUI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new CandadoGUI().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private JButton btnCambiar;
    private JButton btnLock;
    private JButton btnReset;
    private JButton btnSet;
    private JLabel lblIngresados;
    private JPanel pnlBotones;
    private JPanel pnlPantalla;
    private JSpinner spnNumero;
    // End of variables declaration//GEN-END:variables

        private iCandado candado;

	private class ButtonListener implements ActionListener{
            @Override
            public void actionPerformed(ActionEvent e){
                //Obtiene la fuente del evento
                JButton source = (JButton)e.getSource();

                if(source.equals(btnSet)){
                    //Obtiene el numero en el spinner
                    int numero = (int)spnNumero.getValue();

                    //Lo muestra en la lista de numeros ingresados
                    if(lblIngresados.getText().equals("-")){
                        lblIngresados.setText(numero+"");
                    }
                    else{
                        lblIngresados.setText(lblIngresados.getText()+", "+numero);
                    }

                    //Le envia al candado el numero que esta en el spinner
                    if(! candado.press(numero)){
                        //Si ingreso un numero incorrecto bloquea el boton set
                        btnSet.setEnabled(false);
                        btnReset.setEnabled(true);
                    }
                    //Si ingreso un numero correcto, no lo bloquea

                    //Si se desbloqueo el candado
                    if(! candado.isLocked()){
                        //Bloquea el boton set y el boton reset
                        btnSet.setEnabled(false);
                        btnReset.setEnabled(false);

                        //Desbloquea los botones para cerrar el candado y cambiar la clave
                        btnLock.setEnabled(true);
                        btnCambiar.setEnabled(true);
                    }
                }

                else if(source.equals(btnReset)){
                    //Llama al metodo reset del candado
                    candado.reset();

                    //Desbloquea el boton set
                    btnSet.setEnabled(true);

                    //Reinicia el label con la combinacion ingresada
                    lblIngresados.setText("-");
                }

                else if(source.equals(btnLock)){
                    //Llama al metodo del candado para bloquearlo
                    candado.lock();

                    //Desbloquea los botones set y reset
                    btnSet.setEnabled(true);
                    btnReset.setEnabled(true);

                    //Bloquea el boton lock y el boton para cambiar la clave
                    btnLock.setEnabled(false);
                    btnCambiar.setEnabled(false);

                    //Reinicia el label con la combinacion ingresada
                    lblIngresados.setText("-");
                }

                else if(source.equals(btnCambiar)){
                    //Instancia un objeto random para generar una clave aleatoria
                    Random random = new Random();

                    //Si quiere cambiar la clave, se genera una aleatoria
                    int largo = random.nextInt(10)+1;
                    int[] clave = new int[largo];
                    String clave_text = "";

                    //Generara 'largo' números para la nueva contraseña
                    for(int i=0; i<largo; i++){
                        clave[i] = random.nextInt(26);
                        clave_text = clave_text + clave[i] + ", ";
                    }

                    //Muestra la nueva clave al usuario
                    JOptionPane.showMessageDialog(
                            null,
                            "Su nueva clave es: " + clave_text,
                            "NUEVA CLAVE",
                            JOptionPane.INFORMATION_MESSAGE);

                    //Dependiendo de cual candado es, llama al constructor correspondiente
                    if(candado.identify()==1)
                        candado = new Candado1(clave);
                    else
                        candado = new Candado2(clave);
                }
            }
	}
}
